package com.innjia.sys.service.impl;

import com.innjia.base.enums.ContractStatusEnum;
import com.innjia.base.exception.MyException;
import com.innjia.base.utils.PageUtils;
import com.innjia.base.utils.Utils;
import com.innjia.base.utils.ValidatorUtils;
import com.innjia.sys.dao.HouseAuthImageDao;
import com.innjia.sys.dao.HouseDao;
import com.innjia.sys.dao.HouseImageDao;
import com.innjia.sys.dao.HouseOperationLogDao;
import com.innjia.sys.entity.*;
import com.innjia.sys.service.ContractInfoService;
import com.innjia.sys.service.FileService;
import com.innjia.sys.service.HouseService;
import com.innjia.utils.AntianaphylaxisUtils;
import com.innjia.utils.FlowNumUtil;
import org.apache.commons.lang3.StringUtils;
import org.jfree.util.Log;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;


@Service("houseService")
public class HouseServiceImpl implements HouseService {

	private static Logger logger = LoggerFactory.getLogger(HouseServiceImpl.class);

	@Autowired
	private HouseDao houseDao;

	@Autowired
	private HouseImageDao houseImageDao;

	@Autowired
	private HouseAuthImageDao houseAuthImageDao;

	@Autowired
	private HouseOperationLogDao houseOperationLogDao;

	@Autowired
	private FlowNumUtil flowNumUtil;

	@Autowired
	private FileService fileService;

	@Autowired
	private ContractInfoService contractInfoService;
	
	@Override
	public HouseEntity queryObject(String id){
		return houseDao.queryObject(id);
	}
	
	@Override
	public List<HouseEntity> queryList(Map<String, Object> map){
		return houseDao.queryList(map);
	}

    @Override
    public List<HouseEntity> queryListByBean(HouseEntity entity) {
        return houseDao.queryListByBean(entity);
    }
	
	@Override
	public int queryTotal(Map<String, Object> map){
		return houseDao.queryTotal(map);
	}
	
	@Override
	public int save(HouseEntity house){
		house.handleNullProperty();
		return houseDao.save(house);
	}
	
	@Override
	public int update(HouseEntity house){
		if(isHouseWithContract(house.getId())){
			throw new MyException("部分房间有合同在身, 不可编辑");
		}

		house.setUpdateTime(new Date());
        return houseDao.update(house);
	}
	
	@Override
	public int delete(String id){
		if(isHouseWithContract(id)){
			throw new MyException("删除的房间有合同在身, 不可删除");
		}

        return houseDao.delete(id);
	}

	/*
	 * 删除房源， 软删除
	 * 0: 删除
	 */
	public int deleteHouse(HouseEntity houseEntity){
		if(isHouseWithContract(houseEntity.getId())){
			throw new MyException("删除的房间有合同在身, 不可删除");
		}

		houseEntity.setStatus("0");
		houseEntity.setUpdateTime(new Date());

		return houseDao.updateStatus(houseEntity);
	}
	
	@Override
	public int deleteBatch(String[] ids){
        return houseDao.deleteBatch(ids);
	}

	@Override
	public HouseEntity houseInfo(String id){
		return houseDao.houseInfo(id);
	}

	//房东申请房屋出租
	@Override
	@Transactional
	public String apply(HouseEntity houseEntity){
		Date date = new Date();
		if(houseEntity.getId() == null){
			houseEntity.setId(Utils.uuid());
		}

		houseEntity.setCreateTime(date);
		houseEntity.setUpdateTime(date);

		this.save(houseEntity);
		List<HouseImageEntity> images = houseEntity.getHouseImages();

		if(ValidatorUtils.isNotEmpty(images)){

			for(HouseImageEntity image : images){
				image.setHouseId(houseEntity.getId());
				image.setId(Utils.uuid());
			}

			houseImageDao.saveBatch(images);
		}
		return null;
	}
	
	@Override
	public HouseEntity getLatestHouse() {
		return this.houseDao.getLatestHouse();
	}

	@Override
	public HouseEntity findHouseBySerialNum(String serialNum){
		return houseDao.findHouseBySerialNum(serialNum);
	}

	@Override
	@Transactional
	public String create(HouseEntity houseEntity){
		//TODO 检查对应的房东是否存在

		Date currentTime = new Date();
		houseEntity.setCityName("雄安市"); //TODO
		houseEntity.setVersion(1l);
		houseEntity.setId(Utils.uuid());
		houseEntity.setCreateTime(currentTime);
		houseEntity.setUpdateTime(currentTime);
		houseEntity.setStatus("1");
		houseEntity.setRentStatus("空置");
		houseEntity.setApplyStatus("审核通过");
		houseEntity.setCheckerId(houseEntity.getCreatorId()); //TODO, 当前添加和审核放在一步做了
		houseEntity.initHouseType(); //填充房屋户型

		//生成序列号
		String serialNum = flowNumUtil.getHouseSerialNum(3); //重复时, 重试3次
		if(ValidatorUtils.isEmpty(serialNum)){
			logger.error("生成房源序列号失败, 超过重试次数限制.");
			throw new MyException("生成房源序列号失败.");
		}
		houseEntity.setSerialNum(serialNum);

		this.save(houseEntity); //保存大房

		logger.info(String.format("create house by admin, serialNum:%s", serialNum));

		//保存房源图片
		List<HouseImageEntity> images = houseEntity.getHouseImages();
		if(ValidatorUtils.isNotEmpty(images)){
			for(HouseImageEntity image : images){
				image.setHouseId(houseEntity.getId());
				image.setId(Utils.uuid());
			}
			houseImageDao.saveBatch(images);
		}

		//保存房源产权认证图片
		List<HouseAuthImageEntity> authImages = houseEntity.getHouseAuthImages();
		if(ValidatorUtils.isNotEmpty(authImages)){
			for(HouseAuthImageEntity image : authImages){
				image.setHouseId(houseEntity.getId());
				image.setId(Utils.uuid());
			}
			houseAuthImageDao.saveBatch(authImages);
		}

		//创建房源时，合租时才去创建子房间
		if(ValidatorUtils.isEquals("合租", houseEntity.getRentType()) &&
				ValidatorUtils.isNotEmpty(houseEntity.getChildren())){
			List<HouseEntity> children = houseEntity.getChildren();
			for(HouseEntity temp : children){
				//创建子房间
				createChildHouse(temp, houseEntity);
			}
		}

		//生成房源操作日志
		HouseOperationLogEntity houseOperationLogEntity = new HouseOperationLogEntity();
		houseOperationLogEntity.setCreateTime(currentTime);
		houseOperationLogEntity.setHouseId(houseEntity.getId());
		houseOperationLogEntity.setId(Utils.uuid());
		houseOperationLogEntity.setOperation("创建");
		houseOperationLogEntity.setUserId(houseEntity.getCreatorId());
		houseOperationLogDao.save(houseOperationLogEntity);

		return houseEntity.getSerialNum();
	}
	
	@Override
	public List<HouseEntity> queryListByBeanPage(HouseEntity houseEntity, PageUtils pageUtils) {
		int total = this.houseDao.totalByBean(houseEntity);
		pageUtils.setTotalCount(total);
		List<HouseEntity> list = houseDao.queryListByBeanPage(houseEntity, pageUtils );
		for (HouseEntity entity : list) {
			if(StringUtils.equals(entity.getRentType(), "合租")) {
				String parentId = entity.getId();
				List<HouseEntity> children = houseDao.queryChildrenByParentId(parentId);
				entity.setChildren(children);
			}
		}
		return list;
	}

	@Override
	public HouseEntity queryDetailById(String houseId) {
		List<HouseEntity> list = this.houseDao.queryDetailById(houseId);
		/*//合租变整租的父房源，移除子房源
		if(ValidatorUtils.isNotEmpty(list)){
			HouseEntity house = list.get(0);
			if(StringUtils.equals(house.getRentType(),"整租") && ValidatorUtils.isNotEmpty(house.getChildren())){
				house.setChildren(new ArrayList<HouseEntity>());
			}
			return house;
		}else {
			return null;
		}*/
		return ValidatorUtils.isEmpty(list) ? null : list.get(0);
	}

	@Override
	public List<HouseEntity> queryChildrenByParentId(String parentId) {
		List<HouseEntity> children = this.houseDao.queryChildrenByParentId(parentId);
		return children;
	}

	/*
	 * 修改房源信息
	 * @param houseEntity 前端提交
	 * @param oldHouse 当前DB
	 */
	@Override
	@Transactional
	public void reset(HouseEntity houseEntity, HouseEntity oldHouse){
		HouseEntity model = new HouseEntity();
		model.setId(houseEntity.getId());
		model.setVersion(houseEntity.getVersion());

		boolean changed = false;
		boolean rentTypeChanged = false;
		if(ValidatorUtils.isNotEqualsIgnoreNull(houseEntity.getDistrictName(), oldHouse.getDistrictName())){
			changed = true;
			model.setDistrictName(houseEntity.getDistrictName() == null ? "" : houseEntity.getDistrictName());
		}
		if(ValidatorUtils.isNotEqualsIgnoreNull(houseEntity.getAddress(), oldHouse.getAddress())){
			changed = true;
			model.setAddress(houseEntity.getAddress() == null ? "" : houseEntity.getAddress());
		}
		if(ValidatorUtils.isNotEqualsIgnoreNull(houseEntity.getVilage(), oldHouse.getVilage())){
			changed = true;
			model.setVilage(houseEntity.getVilage() == null ? "" : houseEntity.getVilage());
		}
		if(ValidatorUtils.isNotEqualsIgnoreNull(houseEntity.getBlockNo(), oldHouse.getBlockNo())){
			changed = true;
			model.setBlockNo(houseEntity.getBlockNo() == null ? "" : houseEntity.getBlockNo());
		}
		if(ValidatorUtils.isNotEqualsIgnoreNull(houseEntity.getUnitNo(), oldHouse.getUnitNo())){
			changed = true;
			model.setUnitNo(houseEntity.getUnitNo() == null ? "" : houseEntity.getUnitNo());
		}
		if(ValidatorUtils.isNotEqualsIgnoreNull(houseEntity.getFloorNo(), oldHouse.getFloorNo())){
			changed = true;
			model.setFloorNo(houseEntity.getFloorNo() == null ? "" : houseEntity.getFloorNo());
		}
		if(ValidatorUtils.isNotEqualsIgnoreNull(houseEntity.getRoomNo(), oldHouse.getRoomNo())){
			changed = true;
			model.setRoomNo(houseEntity.getRoomNo() == null ? "" : houseEntity.getRoomNo());
		}
		if(ValidatorUtils.isNotEqualsIgnoreNull(houseEntity.getHardware(), oldHouse.getHardware())){
			changed = true;
			model.setHardware(houseEntity.getHardware() == null ? "" : houseEntity.getHardware());
		}
		if(ValidatorUtils.isNotEqualsIgnoreNull(houseEntity.getRemark(), oldHouse.getRemark())){
			changed = true;
			model.setRemark(houseEntity.getRemark() == null ? "" : houseEntity.getRemark());
		}
		if(ValidatorUtils.isNotEqualsIgnoreNull(houseEntity.getBedroomCnt(), oldHouse.getBedroomCnt())
				|| ValidatorUtils.isNotEqualsIgnoreNull(houseEntity.getParlourCnt(), oldHouse.getParlourCnt())
				|| ValidatorUtils.isNotEqualsIgnoreNull(houseEntity.getToiletCnt(), oldHouse.getToiletCnt())){
			changed = true;
			model.setBedroomCnt(houseEntity.getBedroomCnt() == null ? "" : houseEntity.getBedroomCnt());
			model.setParlourCnt(houseEntity.getParlourCnt() == null ? "" : houseEntity.getParlourCnt());
			model.setToiletCnt(houseEntity.getToiletCnt() == null ? "" : houseEntity.getToiletCnt()) ;
			model.initHouseType(); //填充户型信息
		}
		if(ValidatorUtils.isNotEqualsIgnoreNull(houseEntity.getRentType(), oldHouse.getRentType())){
			changed = true;
			rentTypeChanged = true;
			model.setRentType(houseEntity.getRentType() == null ? "" : houseEntity.getRentType());
		}

		//以上信息变更时, 如果合租, 需要更新同步更新子房间信息,
		boolean houseInfoChanged = changed;
		logger.info("house info changed: " + houseInfoChanged);

		if(ValidatorUtils.isNotEqualsIgnoreNull(houseEntity.getDoor(), oldHouse.getDoor())){
			changed = true;
			model.setDoor(houseEntity.getDoor() == null ? "" : houseEntity.getDoor());
		}
		if(ValidatorUtils.isNotEqualsIgnoreNull(houseEntity.getDirect(), oldHouse.getDirect())){
			changed = true;
			model.setDirect(houseEntity.getDirect() == null ? "" : houseEntity.getDirect());
		}
		if(ValidatorUtils.isNotEqualsIgnoreNull(houseEntity.getBuildingArea(), oldHouse.getBuildingArea())){
			changed = true;
			model.setBuildingArea(houseEntity.getBuildingArea() == null ? "" : houseEntity.getBuildingArea());
		}
		if(ValidatorUtils.isNotEqualsIgnoreNull(houseEntity.getRentalPrice(), oldHouse.getRentalPrice())){
			changed = true;
			model.setRentalPrice(houseEntity.getRentalPrice() == null ? "" : houseEntity.getRentalPrice());
		}
		if(ValidatorUtils.isNotEqualsIgnoreNull(houseEntity.getPayMode(), oldHouse.getPayMode())){
			changed = true;
			model.setPayMode(houseEntity.getPayMode() == null ? "" : houseEntity.getPayMode());
		}

		//处理图片变更===========================查看图片信息是否变更(根据Id 是否存在)=====================================
		//1. 房源图片
		List<HouseImageEntity> houseImages = houseEntity.getHouseImages();
		List<HouseImageEntity> oldHouseImages = oldHouse.getHouseImages();
		List<HouseImageEntity> newHouseImages = new ArrayList<>();
		List<HouseImageEntity> deleteHouseImages = new ArrayList<>();//需要删除的图片
		if(ValidatorUtils.isEmpty(houseImages)){
			houseImages = new ArrayList<>();
		}
		if(ValidatorUtils.isEmpty(oldHouseImages)){
			oldHouseImages = new ArrayList<>();
		}
		//找出新增的图片
		for (HouseImageEntity houseImage : houseImages) {
			if(ValidatorUtils.isEmpty(houseImage.getId())){
				//认为是重新添加的图片
				newHouseImages.add(houseImage);
				continue;
			}
		}
		//找出被删除的图片
		for (HouseImageEntity oldHouseImage : oldHouseImages) {
			boolean deleted = true;
			for (HouseImageEntity houseImage : houseImages) {
				if(ValidatorUtils.isEquals(oldHouseImage.getId(), houseImage.getId())){
					deleted = false;
					break;
				}
			}
			if(deleted){
				deleteHouseImages.add(oldHouseImage);
			}
		}
		if(newHouseImages.size() > 0 || deleteHouseImages.size() > 0){
			changed = true;

			if(ValidatorUtils.isNotEmpty(newHouseImages)){
				for(HouseImageEntity image : newHouseImages){
					image.setHouseId(houseEntity.getId());
					image.setId(Utils.uuid());
				}
				houseImageDao.saveBatch(newHouseImages);
			}
			if(ValidatorUtils.isNotEmpty(deleteHouseImages)){
				List<String> deleteIds = new ArrayList<>(deleteHouseImages.size());
				for(HouseImageEntity imageDelete : deleteHouseImages){
					deleteIds.add(imageDelete.getId());
				}
				houseImageDao.deleteBatch(deleteIds.toArray());
			}
		}

		//2. authImage 房源产权图片
		List<HouseAuthImageEntity> houseAuthImages = houseEntity.getHouseAuthImages();
		List<HouseAuthImageEntity> oldHouseAuthImages = oldHouse.getHouseAuthImages();
		List<HouseAuthImageEntity> newHouseAuthImages = new ArrayList<>();
		List<HouseAuthImageEntity> deleteHouseAuthImages = new ArrayList<>();  //需要删除的图片

		if(ValidatorUtils.isEmpty(houseAuthImages)){
			houseAuthImages = new ArrayList<>();
		}
		if(ValidatorUtils.isEmpty(oldHouseAuthImages)){
			oldHouseAuthImages = new ArrayList<>();
		}
		//找出新增的图片
		for (HouseAuthImageEntity houseAuthImageEntity: houseAuthImages) {
			if(ValidatorUtils.isEmpty(houseAuthImageEntity.getId())){
				//认为是重新添加的图片
				newHouseAuthImages.add(houseAuthImageEntity);
				continue;
			}
		}
		//找出被删除的图片
		for (HouseAuthImageEntity oldHouseAuthImage : oldHouseAuthImages) {
			boolean deleted = true;
			for (HouseAuthImageEntity houseAuthImage : houseAuthImages) {
				if(ValidatorUtils.isEquals(oldHouseAuthImage.getId(), houseAuthImage.getId())){
					deleted = false;
					break;
				}
			}
			if(deleted){
				deleteHouseAuthImages.add(oldHouseAuthImage);
			}
		}

		if(newHouseAuthImages.size() > 0 || deleteHouseAuthImages.size() > 0){
			changed = true;
			if(ValidatorUtils.isNotEmpty(newHouseAuthImages)){
				for(HouseAuthImageEntity image : newHouseAuthImages){
					image.setHouseId(houseEntity.getId());
					image.setId(Utils.uuid());
				}
				houseAuthImageDao.saveBatch(newHouseAuthImages);
			}

			if(ValidatorUtils.isNotEmpty(deleteHouseAuthImages)){
				List<String> deleteIds = new ArrayList<>(deleteHouseAuthImages.size());
				for(HouseAuthImageEntity imageDelete : deleteHouseAuthImages){
					deleteIds.add(imageDelete.getId());
				}
				houseAuthImageDao.deleteBatch(deleteIds.toArray());
			}
		}

		//处理图片变更=================================================================  END ===

		//处理子房间
		List<HouseEntity> children = houseEntity.getChildren();
		List<HouseEntity> oldChildren = oldHouse.getChildren();
		List<HouseEntity> newChildren = new ArrayList<>();
		List<HouseEntity> deleteChildren = new ArrayList<>();
		List<HouseEntity> modifyChildren = new ArrayList<>();
		if(children == null){
			children = new ArrayList<>();
		}
		if(oldChildren == null){
			oldChildren = new ArrayList<>();
		}
		if(rentTypeChanged){
			if(ValidatorUtils.isEquals("合租", houseEntity.getRentType())){
				//整租 -> 合租
				//1.处理前台传来的不带 ID 的子房间
				for(HouseEntity temp : children){
					if(ValidatorUtils.isEmpty(temp.getId())){
						//判断相同房源信息的子房间是否存在
						HouseEntity houseExist = getHouseEntityByModel(oldHouse, temp);
						if(ValidatorUtils.isNotEmpty(houseExist)){
							temp.setId(houseExist.getId());
							temp.setStatus("1"); //有可能房间之前被删除了
							temp.setVersion(houseExist.getVersion());
							modifyChildren.add(temp); //视为编辑
						}else{
							newChildren.add(temp);    //视为新增
						}
					}
				}
				//2. 获得修改或者删除的房间
				for(HouseEntity oldTemp : oldChildren){
					boolean deleted = true;
					for(HouseEntity temp : children){
						if(ValidatorUtils.isEquals(oldTemp.getId(), temp.getId())){
							deleted = false;
							if(houseInfoChanged || ValidatorUtils.isNotEqualsIgnoreNull(oldTemp.getDoor(), temp.getDoor())
									|| ValidatorUtils.isNotEqualsIgnoreNull(oldTemp.getBuildingArea(), temp.getBuildingArea())
									|| ValidatorUtils.isNotEqualsIgnoreNull(oldTemp.getDirect(),temp.getDirect())
									|| ValidatorUtils.isNotEqualsIgnoreNull(oldTemp.getRentalPrice(), temp.getRentalPrice())
									|| ValidatorUtils.isNotEqualsIgnoreNull(oldTemp.getPayMode(), temp.getPayMode())){

								temp.setVersion(oldTemp.getVersion());
								modifyChildren.add(temp);
							}
							break;
						}
					}
					//判断是否在第一步已经放入待编辑(子)房源了
					for(HouseEntity modify : modifyChildren){
						if(ValidatorUtils.isEquals(oldTemp.getId(), modify.getId())){
							deleted = false;
							break;
						}
					}

					if(deleted){
						deleteChildren.add(oldTemp);
					}
				}

			}else{
				//合租 -> 整租;  不删除子房间, 只是同步更新子房间信息
				modifyChildren = oldChildren;
				//deleteChildren = oldChildren;
			}
		}else if(ValidatorUtils.isEquals("合租", houseEntity.getRentType())){
			//依旧为合租

			//1.处理前台传来的不带 ID 的子房间
			for(HouseEntity temp : children){
				if(ValidatorUtils.isEmpty(temp.getId())){
					//判断相同房源信息的子房间是否存在
					HouseEntity houseExist = getHouseEntityByModel(oldHouse, temp);
					if(ValidatorUtils.isNotEmpty(houseExist)){
						temp.setId(houseExist.getId());
						temp.setVersion(houseExist.getVersion());
						temp.setStatus("1"); //有可能房间之前被删除了
						modifyChildren.add(temp); //视为编辑
					}else{
						newChildren.add(temp);    //视为新增
					}
				}
			}
			//2. 获得修改或者删除的房间
			for(HouseEntity oldTemp : oldChildren){
				boolean deleted = true;
				for(HouseEntity temp : children){
					if(ValidatorUtils.isEquals(oldTemp.getId(), temp.getId())){
						deleted = false;
						if(houseInfoChanged || ValidatorUtils.isNotEqualsIgnoreNull(oldTemp.getDoor(), temp.getDoor())
								|| ValidatorUtils.isNotEqualsIgnoreNull(oldTemp.getBuildingArea(), temp.getBuildingArea())
								|| ValidatorUtils.isNotEqualsIgnoreNull(oldTemp.getDirect(),temp.getDirect())
								|| ValidatorUtils.isNotEqualsIgnoreNull(oldTemp.getRentalPrice(), temp.getRentalPrice())
								|| ValidatorUtils.isNotEqualsIgnoreNull(oldTemp.getPayMode(), temp.getPayMode())){

							temp.setVersion(oldTemp.getVersion());
							modifyChildren.add(temp);
						}
						break;
					}
				}
				//判断是否在第一步已经放入待编辑(子)房源了
				for(HouseEntity modify : modifyChildren){
					if(ValidatorUtils.isEquals(oldTemp.getId(), modify.getId())){
						deleted = false;
						break;
					}
				}
				if(deleted){
					deleteChildren.add(oldTemp);
				}
			}
		}else{
			//依旧是整租; 如果父房源信息变了, 需要同步更新子房源
			if(houseInfoChanged){
				modifyChildren = oldChildren;
			}
		}

		if(newChildren.size() > 0 || modifyChildren.size() > 0 || deleteChildren.size() > 0){
			changed = true;
		}

		if(changed){
			int updateSize = this.update(model);
			if(updateSize <= 0){
				Log.warn("更新房间信息时失败, 房源 version 已变更");
				throw new MyException("请刷新后再试");
			}

			HouseEntity currentHouse = this.queryObject(model.getId());
			if(deleteChildren.size() > 0){
				for(HouseEntity temp : deleteChildren){
					//this.delete(temp.getId());
					int updated = deleteHouse(temp); //软删除
					if(updated <= 0){
						Log.warn("更新房间信息时失败, 房源 version 已变更");
						throw new MyException("请刷新后再试");
					}

					logger.info(String.format("delete house(child) by admin, serialNum:%s", temp.getSerialNum()));
				}
			}
			if(modifyChildren.size() > 0){
				//这里使用的 model, 房屋信息已经和最新的大门信息一致了
				for(HouseEntity temp : modifyChildren){
					model.setId(temp.getId());
					model.setVersion(temp.getVersion());
					model.setDoor(temp.getDoor());
					model.setBuildingArea(temp.getBuildingArea());
					model.setDirect(temp.getDirect());
					model.setRentalPrice(temp.getRentalPrice());
					model.setPayMode(temp.getPayMode());

					this.update(model);
				}
			}

			if(newChildren.size() > 0){
				for(HouseEntity temp : newChildren){
					//创建子房间
					createChildHouse(temp, currentHouse);
				}
			}
		}
	}

	//根据大门创建子房间
	private void createChildHouse(HouseEntity childInfo, HouseEntity parent){
		HouseEntity child = parent.fastGenChildRoom();
		child.setDoor(childInfo.getDoor());
		child.setBuildingArea(childInfo.getBuildingArea());
		child.setDirect(childInfo.getDirect());
		child.setRentalPrice(childInfo.getRentalPrice());
		child.setPayMode(childInfo.getPayMode());

		//生成序列号
		String serialNumTemp = flowNumUtil.getHouseSerialNum(3); //重复时, 重试3次
		if(ValidatorUtils.isEmpty(serialNumTemp)){
			logger.error("生成房源序列号失败, 超过重试次数限制.");
			throw new MyException("生成房源序列号失败.");
		}
		child.setSerialNum(serialNumTemp);

		this.save(child); //保存子房间

		logger.info(String.format("create house by admin, serialNum:%s", serialNumTemp));
	}


	@Override
	public HouseEntity getHouseById(String houseId) {
		HouseEntity entity = this.houseDao.queryObject(houseId);
		return entity;
	}

	@Override
	@Transactional
	public void updateRentStatus(HouseEntity house, String rentStatus) {
		//判断是整租还是合租
		HouseEntity entity = new HouseEntity();
		if(StringUtils.equals(house.getRentType(), "整租")) {
			//整租，直接修改
			entity.setId(house.getId());
			entity.setRentStatus(rentStatus);
			entity.setUpdateTime(new Date());
			this.houseDao.updateRentStatus(entity);
			//添加对整租父房源下包含整租子房源的支持
			List<HouseEntity> children = this.houseDao.queryChildrenByParentId(house.getId());
			if(ValidatorUtils.isNotEmpty(children)){
				for (HouseEntity child:children) {
					entity.setId(child.getId());
					this.houseDao.updateRentStatus(entity);
				}
			}
		}else if(StringUtils.equals(house.getRentType(), "合租")) {
			//合租
			//1.修改的是父房源的出租状态
			if(StringUtils.isBlank(house.getParentId())) {
				entity.setId(house.getId());
				entity.setRentStatus(rentStatus);
				entity.setUpdateTime(new Date());
				this.houseDao.updateRentStatus(entity);
				return;
			
			
			}else {
				//2.修改的是子房源的出租状态，需要同步修改父房源的出租状态
				if(StringUtils.equals(house.getRentType(), "部分出租")) {
					//子房源没有此状态
					throw new MyException("子房源的出租状态不能修改为：部分出租");
				}
				List<HouseEntity> children = this.houseDao.queryChildrenByParentId(house.getParentId());
				//修改当前子房间的状态
				entity.setId(house.getId());
				entity.setRentStatus(rentStatus);
				entity.setUpdateTime(new Date());
				this.houseDao.updateRentStatus(entity);
				for (HouseEntity child : children) {
					if(!child.getId().equals(house.getId())) {
						if(!StringUtils.equals(child.getRentStatus(), rentStatus)){
							//子房间出租关系出现互斥，当前父房源状态应该为：部分出租
							entity.setId(house.getParentId());
							entity.setRentStatus("部分出租");
							entity.setUpdateTime(new Date());
							this.houseDao.updateRentStatus(entity);
							return;
						}
					}
				}
				//所有子房间的出租状态一致，父房源的状态应该和当前房源保持一致
				entity.setId(house.getParentId());
				entity.setRentStatus(rentStatus);
				entity.setUpdateTime(new Date());
				this.houseDao.updateRentStatus(entity);
			}
		}
	}

	@Override
	public List<HouseEntity> queryAppList(HouseEntity houseEntity, PageUtils pageUtils) {
		int total = this.houseDao.AppTotalByBean(houseEntity);
		pageUtils.setTotalCount(total);
		List<HouseEntity> list = houseDao.queryAppListByBeanPage(houseEntity, pageUtils );
		return list;
	}

	/*
	 * 一个房源下任意一个房间有合同在身， 都视为房源有合同在身
	 */
	@Override
	public boolean isHouseWithContract(String houseId){
		ContractInfoEntity contractInfo = contractInfoService.queryHouseId(houseId);

		if(ValidatorUtils.isNotEmpty(contractInfo)
				&& (ValidatorUtils.isEquals(ContractStatusEnum.WAIT_SIGN.getCode(), contractInfo.getContractStatus())
				|| ValidatorUtils.isEquals(ContractStatusEnum.SIGNED.getCode(), contractInfo.getContractStatus()))){
			return true;
		}

		List<HouseEntity> children = queryChildrenByParentId(houseId);
		if(ValidatorUtils.isNotEmpty(children)){
			for (HouseEntity child : children){
				contractInfo = contractInfoService.queryHouseId(child.getId());

				if(ValidatorUtils.isNotEmpty(contractInfo)
						&& (ValidatorUtils.isEquals(ContractStatusEnum.WAIT_SIGN.getCode(), contractInfo.getContractStatus())
						|| ValidatorUtils.isEquals(ContractStatusEnum.SIGNED.getCode(), contractInfo.getContractStatus()))){
					return true;
				}
			}
		}

        return false;
    }
	
	@Override
	public List<HouseEntity> queryListByLandlordId(String landlordId, PageUtils pageUtils) {
		int total = this.houseDao.AppTotalByLandlordId(landlordId);
		pageUtils.setTotalCount(total);
		List<HouseEntity> houses = this.houseDao.queryListByLandlordId(landlordId,pageUtils);
		if(ValidatorUtils.isEmpty(houses)) {
			logger.info("未找到landlordId" + landlordId + "对应的房源");
			return new ArrayList<HouseEntity>();
		}

		for (HouseEntity house : houses) {
			//添加对合租变整租的支持，将此情况下整租父房源的子房源置空
			if(StringUtils.equals(house.getRentType(), "整租")
					&& ValidatorUtils.isNotEmpty(house.getChildren())){
				house.setChildren(new ArrayList<HouseEntity>());
			}

			//添加合同中的租客信息
			if(StringUtils.equals(house.getRentType(), "整租")
					&& StringUtils.equals(house.getRentStatus(), "已出租")) {
				List<ContractInfoEntity> contractInfoes = new ArrayList<>();
				ContractInfoEntity model = new ContractInfoEntity();
				ContractInfoEntity contractInfo = this.contractInfoService.queryHouseId(house.getId());
				if(contractInfo == null) {
					logger.info("未查到房源id:" + house.getId() + "对应的合同信息");
					model.setTenantName("");
				} else {
					model.setTenantName(StringUtils.isBlank(contractInfo.getTenantName()) ? "" : contractInfo.getTenantName());
				}
				contractInfoes.add(model);
				house.setContractInfos(contractInfoes);

			}else if(StringUtils.equals(house.getRentType(), "合租") 
				&& ((StringUtils.equals(house.getRentStatus(), "已出租")) 
				|| (StringUtils.equals(house.getRentStatus(), "部分出租")))) {
				List<HouseEntity> children = house.getChildren();
				if(children == null) {
					logger.info("合租房源未找到子房源");
					throw new MyException("合租房源未找到子房源");
				}
				for (HouseEntity child : children) {
					if(StringUtils.equals(child.getRentStatus(), "已出租")) {
						List<ContractInfoEntity> contractInfoes = new ArrayList<>();
						ContractInfoEntity model = new ContractInfoEntity();
						ContractInfoEntity contractInfo = this.contractInfoService.queryHouseId(child.getId());
						if(contractInfo == null) {
							logger.info("未查到房源id:" + child.getId() + "对应的合同信息");
							model.setTenantName("");
						}else {
							model.setTenantName(StringUtils.isBlank(contractInfo.getTenantName()) ? "" : contractInfo.getTenantName());
						}
						contractInfoes.add(model);
						child.setContractInfos(contractInfoes);
					}
				}
			}
		}
		return houses;
	}

	
	@Override
	public boolean updateRentStatusByHouseId(String houseId, String rentStatus) {
		if(StringUtils.isBlank(houseId) || StringUtils.isBlank(rentStatus) || 
		((!StringUtils.equals(rentStatus, "空置")) && (!StringUtils.equals(rentStatus, "已出租"))
			&& (!StringUtils.equals(rentStatus, "部分出租")))){
			return false;
		}
		try {
			HouseEntity house = this.houseDao.queryObject(houseId);
			if(house == null) {
				return false;
			}
			updateRentStatus(house, rentStatus);
			return true;
		} catch (Exception e) {
			logger.error(e.getMessage(),e);
			return false;
		}
	}
	
	public List<HouseEntity> transferAllPhones(List<HouseEntity> houses){
		if(ValidatorUtils.isNotEmpty(houses)) {
			for (HouseEntity entity : houses) {
				if(ValidatorUtils.isNotEmpty(entity.getLandlord()) && StringUtils.isNotBlank(entity.getLandlord().getPhone())) {
					String newPhone = AntianaphylaxisUtils.transferPhone(entity.getLandlord().getPhone());
					entity.getLandlord().setPhone(newPhone);
				}
				if(StringUtils.isNotBlank(entity.getOwnerPhone())) {
					String newPhone = AntianaphylaxisUtils.transferPhone(entity.getOwnerPhone());
					entity.setOwnerPhone(newPhone);
				}
			}
		}
		return houses;
	}

	/*
	 * 查找相应房源是否存在
	 * (`city_name`,`district_name`,`address`,`vilage`,`block_no`,`unit_no`,`room_no`,`floor_no`,`door`)
	 */
	private HouseEntity getHouseEntityByModel(HouseEntity parent, HouseEntity house){
		HouseEntity model = new HouseEntity();
		if(parent != null){
			if(parent.getId() != null){
				model.setParentId(parent.getId());
			}else{
				model.setCityName(parent.getCityName());
				model.setDistrictName(parent.getDistrictName());
				model.setAddress(parent.getAddress());
				model.setVilage(parent.getVilage());
				model.setBlockNo(parent.getBlockNo());
				model.setUnitNo(parent.getUnitNo());
				model.setFloorNo(parent.getFloorNo());
			}
		}else{
			model.setCityName(house.getCityName());
			model.setDistrictName(house.getDistrictName());
			model.setAddress(house.getAddress());
			model.setVilage(house.getVilage());
			model.setBlockNo(house.getBlockNo());
			model.setUnitNo(house.getUnitNo());
			model.setFloorNo(house.getFloorNo());
		}

		model.setDoor(house.getDoor());

		return houseDao.findByUniqueKey(model);
	}
}
